#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "/usr/local/include/pbc/pbc.h"
#include "/usr/local/include/pbc/pbc_test.h"
#include <math.h>

#define NMAX 1000 //block number
#define S 100//challlenge number
#define  CMAX  1000//challlenge number

	//生成文件

typedef struct 
{
	element_t m[NMAX], auth[NMAX];
}File;
File f;



typedef struct  
{
	int cj[NMAX];
	element_t cvj[NMAX];
}Challenge;
Challenge c;


double t1, t2;
int i, j;


int main(int argc, char **argv) {


FILE *fp;//文件指针

    fp=fopen("data.txt","w");//fopen打开文件，这个文件可以是当前不存在的。“w”以写入的形式打开，“r”以读的形式打开
    if(fp==NULL) //判断如果文件指针为空
    {
        printf("File cannot open! " );
        exit(0);//在以0的形式退出，必须在文件开头有#include <stdlib.h>,stdlib 头文件即standard library标准库头文件
    }



	//系统参数
	pairing_t pairing;
	pbc_demo_pairing_init(pairing, argc, argv);

  	element_t y, x, g;	
	element_init_Zr(x, pairing);
	element_random(x);	
	element_init_G1(y, pairing);
	element_init_G1(g, pairing);
	element_random(g);
	element_pow_zn(y, g, x);
	
	element_t uk[NMAX];
	for ( i = 0; i < NMAX; i++ )
	{
		element_init_Zr(f.m[i], pairing);
		element_random(f.m[i]);
		element_init_G1(uk[i], pairing);
		element_random(uk[i]);
	}
	element_t IDF;
	element_init_Zr(IDF, pairing);
	element_random(IDF);
	
	element_t BNj[S], BVj[S];
	for(j=0;j<S;j++)
	{
		element_init_Zr(BNj[j], pairing);
		element_init_Zr(BVj[j], pairing);
		element_random(BNj[j]);
		element_random(BVj[j]);
	}
	
//AuthGen
	element_t H[S];
for(int N=100;N<1001;N+=100)
	//int N=1000;
{
		
	t1=pbc_get_time();
	for(j=0;j<S;j++)
	{
        element_init_G1(H[j], pairing);
        element_from_hash(H[j], (char *)"IDF || BNj[j] || BVj[j]", sizeof("IDF || BNj[j] || BVj[j]"));
    }
	
	int sector=N/S;
	
	double t3=pbc_get_time();
	element_t ukbijk[sector], Mul_ub;
	element_init_G1(Mul_ub, pairing);
	element_set1(Mul_ub);
	for(int k=0;k<sector;k++)
	{
		element_init_G1(ukbijk[k], pairing);
		element_pow_zn(ukbijk[k], uk[k], f.m[k]);
		element_mul(Mul_ub, Mul_ub, ukbijk[k]);
	}
	double t4=pbc_get_time();
	double t_Mul_ub = (t4-t3)*(S-1);//认证器加上这个时间
	
	for(j=0;j<S;j++)
	{
		element_init_G1(f.auth[j], pairing);
		element_mul(f.auth[j], H[j], Mul_ub);
		element_pow_zn(f.auth[j], f.auth[j], x);
	}
	
	t2=pbc_get_time();
	
	double t_AuthGen = t2-t1 + t_Mul_ub;

	fprintf(fp, "认证器生成时间 = %f\n", t_AuthGen);
}


fprintf(fp, "=============================================================\n");
fprintf(fp, "质询阶段，数据块数量 = 1000 \n");
	   
	element_t au1[NMAX], AP1;
	//au2和miu2是最终版
	element_init_Zr(AP1,pairing);
	element_set0(AP1);

	
for(int C = 10; C<101; C+=10)
{	
//int C=100;
	fprintf(fp, "被质询的数据块数量 = %d\n", C);
//ChallengeGen

	t1 = pbc_get_time();
	
	
	
	for(j = 0; j < C; j++)
	{					
		element_init_Zr(c.cvj[j], pairing);
		element_random(c.cvj[j]);
	}
	
	t2 = pbc_get_time();		
	//fprintf(fp, "质询生成时间 = %f\n", t2 - t1);	

//ProofGen
    t1 = pbc_get_time();
	
	element_t sigma, sigma2[C], miu, miu2[10], miu3[C];
	element_init_G1(sigma, pairing);
	element_set1(sigma);
	element_init_Zr(miu, pairing);
	//element_set0(miu);
	for(j = 0; j < C; j++)
	{	
		element_init_G1(sigma2[j], pairing);
		element_pow_zn(sigma2[j], f.auth[j], c.cvj[j]);
		element_mul(sigma, sigma, sigma2[j]);		
	}
	
	for(int k=0;k<10;k++)
	{
		element_set0(miu);
		for(j=0;j < C; j++)
		{
			element_init_Zr(miu3[j], pairing);
			element_mul(miu3[j], c.cvj[j], f.m[k]);
			element_add(miu, miu, miu3[j]);
		}
		element_init_Zr(miu2[k], pairing);
		element_set(miu2[k], miu);	
	}
	
	t2 = pbc_get_time();		
	fprintf(fp, "ProofGen时间 = %f\n", t2 - t1);	
	
//ProofVerify
    t1 = pbc_get_time();
     
    element_t Hc2[C], Hc;
	element_init_G1(Hc, pairing);
	element_set1(Hc);
       
	for (j = 0; j < C; j++)
	{		
		element_init_G1(Hc2[j], pairing);
		element_from_hash(Hc2[j], (char *)"IDF || BNj[j] || BVj[j]", sizeof("IDF || BNj[j] || BVj[j]"));
		element_pow_zn(Hc2[j], Hc2[j], c.cvj[j]);
		element_mul(Hc, Hc, Hc2[j]);
	}//得到H
	
	element_t umiu, umiu2[10];
	element_init_G1(umiu, pairing);
	element_set1(umiu);
	for(int k=0;k<10;k++)
	{
		element_init_G1(umiu2[k], pairing);
		element_pow_zn(umiu2[k], uk[k], miu2[k]);
		element_mul(umiu, umiu, umiu2[k]);
	}
	
	element_t right1;
	element_init_G1(right1, pairing);
	element_mul(right1, Hc, umiu);
	
	element_t e1, e2;
	element_init_GT(e1, pairing);
	element_init_GT(e2, pairing);
	
	pairing_apply(e1, sigma, g, pairing);
	pairing_apply(e2, right1, y, pairing);
	
	
	if(!element_cmp(e1, e2) )
	{
		printf("success\n");
	}
	else{printf("fail\n");}
	
	
	
	t2 = pbc_get_time();
	
	fprintf(fp, "ProofVerify时间 = %f\n", t2 - t1);
	fprintf(fp, "\n");
	
}
/*
*/

	
	 //关闭文件
    	fclose(fp);
	return 0;
}
	
	
	
